package com.anonymous.community.hotfix;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;

/**
 * 热更新服务类
 * 负责检查更新、下载补丁等功能
 */
public class HotfixService {
    
    private static final String TAG = "HotfixService";
    private static final String PREFS_NAME = "hotfix_prefs";
    private static final String KEY_LAST_CHECK_TIME = "last_check_time";
    private static final String KEY_CURRENT_PATCH_VERSION = "current_patch_version";
    
    private Context context;
    private SharedPreferences prefs;
    private HotfixCallback callback;
    
    public interface HotfixCallback {
        void onCheckUpdateResult(UpdateInfo updateInfo);
        void onDownloadProgress(int progress);
        void onDownloadSuccess(String patchPath);
        void onDownloadFailed(String error);
        void onPatchApplyResult(boolean success, String message);
    }
    
    public interface UpdateCheckListener {
        void onSuccess(UpdateInfo updateInfo);
        void onError(String error);
    }
    
    public HotfixService(Context context) {
        this.context = context.getApplicationContext();
        this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    }
    
    public void setCallback(HotfixCallback callback) {
        this.callback = callback;
    }
    
    /**
     * 检查更新（带监听器）
     */
    public void checkForUpdates(UpdateCheckListener listener) {
        if (!HotfixConfig.isHotfixEnabled()) {
            if (listener != null) {
                listener.onError("热更新功能已关闭");
            }
            return;
        }
        
        if (!isNetworkAvailable()) {
            if (listener != null) {
                listener.onError("网络不可用");
            }
            return;
        }
        
        new CheckUpdateTask(listener).execute();
    }
    
    /**
     * 下载补丁文件
     */
    public void downloadPatch(UpdateInfo updateInfo) {
        if (updateInfo == null || !updateInfo.isHasUpdate()) {
            Log.e(TAG, "无效的更新信息");
            return;
        }
        
        // 检查网络状态
        if (!isNetworkAvailable()) {
            if (callback != null) {
                callback.onDownloadFailed("网络不可用");
            }
            return;
        }
        
        // 如果设置了仅WiFi下载，检查是否为WiFi网络
        if (HotfixConfig.isAutoDownloadOnWifi() && !isWifiConnected()) {
            Log.d(TAG, "当前非WiFi网络，跳过自动下载");
            return;
        }
        
        new DownloadPatchTask(updateInfo).execute();
    }
    
    /**
     * 应用补丁
     */
    public void applyPatch(String patchPath) {
        // 这里集成Tinker的补丁应用逻辑
        // 由于Tinker需要在下次启动时应用补丁，这里主要是验证和准备工作
        
        File patchFile = new File(patchPath);
        if (!patchFile.exists()) {
            if (callback != null) {
                callback.onPatchApplyResult(false, "补丁文件不存在");
            }
            return;
        }
        
        // 验证补丁文件
        // 这里可以添加MD5校验等逻辑
        
        // 将补丁文件移动到Tinker指定目录
        // TinkerInstaller.onReceiveUpgradePatch(context, patchPath);
        
        if (callback != null) {
            callback.onPatchApplyResult(true, "补丁准备完成，将在下次启动时生效");
        }
        
        Log.i(TAG, "补丁应用成功: " + patchPath);
    }
    
    /**
     * 获取当前补丁版本
     */
    public String getCurrentPatchVersion() {
        return prefs.getString(KEY_CURRENT_PATCH_VERSION, HotfixConfig.APP_VERSION);
    }
    
    /**
     * 设置当前补丁版本
     */
    public void setCurrentPatchVersion(String version) {
        prefs.edit().putString(KEY_CURRENT_PATCH_VERSION, version).apply();
    }
    
    /**
     * 检查网络是否可用
     */
    private boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
    
    /**
     * 检查是否为WiFi网络
     */
    private boolean isWifiConnected() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
    }
    
    /**
     * 计算文件MD5值
     */
    private String calculateMD5(File file) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            FileInputStream fis = new FileInputStream(file);
            byte[] buffer = new byte[8192];
            int length;
            while ((length = fis.read(buffer)) != -1) {
                md.update(buffer, 0, length);
            }
            fis.close();
            
            byte[] hash = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            Log.e(TAG, "计算MD5失败", e);
            return null;
        }
    }
    
    /**
     * 检查更新的异步任务
     */
    private class CheckUpdateTask extends AsyncTask<Void, Void, UpdateInfo> {
        
        private UpdateCheckListener listener;
        private String errorMessage;
        
        public CheckUpdateTask(UpdateCheckListener listener) {
            this.listener = listener;
        }
        
        @Override
        protected UpdateInfo doInBackground(Void... voids) {
            try {
                URL url = new URL(HotfixConfig.CHECK_UPDATE_URL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                
                // 构建请求参数
                JSONObject requestJson = new JSONObject();
                requestJson.put("packageName", HotfixConfig.PACKAGE_NAME);
                requestJson.put("currentVersion", HotfixConfig.APP_VERSION);
                requestJson.put("currentPatchVersion", getCurrentPatchVersion());
                
                // 发送请求
                OutputStream os = connection.getOutputStream();
                os.write(requestJson.toString().getBytes("UTF-8"));
                os.close();
                
                // 读取响应
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    reader.close();
                    
                    // 解析响应
                    JSONObject responseJson = new JSONObject(response.toString());
                    UpdateInfo updateInfo = new UpdateInfo();
                    updateInfo.setHasUpdate(responseJson.optBoolean("hasUpdate", false));
                    updateInfo.setPatchVersion(responseJson.optString("patchVersion"));
                    updateInfo.setDownloadUrl(responseJson.optString("downloadUrl"));
                    updateInfo.setFileSize(responseJson.optLong("fileSize", 0));
                    updateInfo.setMd5(responseJson.optString("md5"));
                    updateInfo.setDescription(responseJson.optString("description"));
                    updateInfo.setForceUpdate(responseJson.optBoolean("forceUpdate", false));
                    updateInfo.setMinAppVersion(responseJson.optString("minAppVersion"));
                    
                    return updateInfo;
                }
                
            } catch (Exception e) {
                Log.e(TAG, "检查更新失败", e);
                errorMessage = e.getMessage();
            }
            
            return new UpdateInfo(); // 返回空的更新信息
        }
        
        @Override
        protected void onPostExecute(UpdateInfo updateInfo) {
            // 更新最后检查时间
            prefs.edit().putLong(KEY_LAST_CHECK_TIME, System.currentTimeMillis()).apply();
            
            if (listener != null) {
                if (updateInfo != null && updateInfo.isHasUpdate()) {
                    listener.onSuccess(updateInfo);
                } else if (errorMessage != null) {
                    listener.onError(errorMessage);
                } else {
                    listener.onSuccess(updateInfo != null ? updateInfo : new UpdateInfo());
                }
            }
        }
    }
    
    /**
     * 下载补丁的异步任务
     */
    private class DownloadPatchTask extends AsyncTask<Void, Integer, String> {
        
        private UpdateInfo updateInfo;
        private String errorMessage;
        
        public DownloadPatchTask(UpdateInfo updateInfo) {
            this.updateInfo = updateInfo;
        }
        
        @Override
        protected String doInBackground(Void... voids) {
            try {
                URL url = new URL(updateInfo.getDownloadUrl());
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                
                int fileLength = connection.getContentLength();
                
                // 创建补丁目录
                File patchDir = new File(context.getFilesDir(), HotfixConfig.PATCH_DIR);
                if (!patchDir.exists()) {
                    patchDir.mkdirs();
                }
                
                // 创建补丁文件
                String fileName = HotfixConfig.PATCH_FILE_PREFIX + updateInfo.getPatchVersion() + ".apk";
                File patchFile = new File(patchDir, fileName);
                
                InputStream input = new BufferedInputStream(connection.getInputStream());
                OutputStream output = new FileOutputStream(patchFile);
                
                byte[] data = new byte[4096];
                long total = 0;
                int count;
                
                while ((count = input.read(data)) != -1) {
                    total += count;
                    
                    // 发布进度
                    if (fileLength > 0) {
                        publishProgress((int) (total * 100 / fileLength));
                    }
                    
                    output.write(data, 0, count);
                }
                
                output.flush();
                output.close();
                input.close();
                connection.disconnect();
                
                // 验证文件MD5
                String fileMd5 = calculateMD5(patchFile);
                if (updateInfo.getMd5() != null && !updateInfo.getMd5().equals(fileMd5)) {
                    errorMessage = "文件校验失败";
                    patchFile.delete();
                    return null;
                }
                
                return patchFile.getAbsolutePath();
                
            } catch (Exception e) {
                Log.e(TAG, "下载补丁失败", e);
                errorMessage = e.getMessage();
                return null;
            }
        }
        
        @Override
        protected void onProgressUpdate(Integer... progress) {
            if (callback != null) {
                callback.onDownloadProgress(progress[0]);
            }
        }
        
        @Override
        protected void onPostExecute(String patchPath) {
            if (patchPath != null) {
                if (callback != null) {
                    callback.onDownloadSuccess(patchPath);
                }
            } else {
                if (callback != null) {
                    callback.onDownloadFailed(errorMessage != null ? errorMessage : "下载失败");
                }
            }
        }
    }
}